package embyparse.noobparser;

import java.util.ArrayList;
import java.util.List;

import embyparse.parsetree.ParseNode;

/**
 * A compound pattern represents a language construct that is made out of a fixed
 * amount of other constructs.
 * <br>
 * Grouping patterns deal with variable-length constructs.
 * @author Justin
 *
 */
public class CompoundPattern extends Pattern{
	/*
	public static void main(String[] args){
		CompoundPattern testPattern = (CompoundPattern) new CompoundPattern("HI","EXPR","ALL").setSuperPattern("ALL");
		ParseNode i = LiteralNode.generateInt(2,-1);
		ParseNode s = LiteralNode.generateString("poop",-1);
		ParseNode plus = TokenAnalyzer.analyzeToken(new Token("+"));
		ArrayList<ParseNode> stack = new ArrayList<ParseNode>();
		stack.add(i);stack.add(plus);stack.add(s);stack.add(i);stack.add(plus);stack.add(s);
		System.out.println(stack);

		stack = INFIXCALL1.match(stack, null);
		System.out.println("new stack: "+stack);
		System.out.println("-----------");
		stack = testPattern.match(stack, null);
		System.out.println("new stack: "+stack);
		System.out.println("-----------");
		stack = testPattern.match(stack, null);
		System.out.println("new stack: "+stack);
		System.out.println(stack.get(0).children);
		System.out.println(stack.get(0).children.get(0).children);
	}
	*/


	String[] patterns;
	boolean look; //infix lookahead disabled/enabled
	public CompoundPattern(String name, String... patterns) {
		this(0,name,patterns);
	}

	public CompoundPattern(int precedence, String name, String...patterns){
		super(name, precedence);
		this.patterns = patterns;
		look = true;
		PatternDefinitions.MATCHING_PATTERNS.add(this);
	}

	@Override
	public ArrayList<ParseNode> match(ArrayList<ParseNode> stack, ParseNode lookahead){
		if( lookahead != null && this.precedence< lookahead.tag.precedence){
			return stack;
		}

		else{

			if( stack.size()<patterns.length)return stack;

			int match_index = stack.size()-patterns.length;
			for(int i = 0; i<patterns.length; i++){//make sure the entire pattern matches. Iterate left-to-right
				boolean tagmatches = false;
				Pattern tag = stack.get(match_index+i).tag;
				while( tag != null){//CHECK SUPERTAGS!!!
					if (patterns[i].equals(tag.name)){
						tagmatches = true; break;
					}
					tag = tag.superPattern;
				}

				if( tagmatches == false){
					return stack;
				}
			}

			//there is a match!
			List<ParseNode> nested = stack.subList(match_index, stack.size());

			ArrayList<ParseNode> nestedList = new ArrayList<ParseNode>();
			for(int i = 0; i<nested.size();i++){
				nestedList.add(nested.get(i));
			}

			ParseNode node = new ParseNode(this,null,nestedList);
			node.setLine(nested.get(0).lineNumber);

			for(int i = 0; i<patterns.length;i++){
				stack.remove(stack.size()-1);
			}
			stack.add(node);

			if(m!=null)m.matchFound();
			return stack;
		}
	}
}
